package com.mach.platform.service;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.mach.platform.domain.base.Account;
import com.mach.platform.repository.AccountRepo;
import com.mach.platform.utils.IdentityUtil;
import com.mach.platform.utils.PinYinUtil;
import com.mach.platform.utils.springdata.DynamicSpecifications;
import com.mach.platform.utils.springdata.SearchFilter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * @author Anonymous
 * @Description: 用户接口实现类
 * @Package: com.mach.platform.com.mach.platform.service
 * @time 2018/04/03 22:52
 */
@Service
public class AccountServiceImpl implements AccountService {

	@Autowired
	private AccountRepo accountRepo;

	/**
	 * 保存
	 *
	 * @param account 保存的实体
	 * @return Account
	 */
	@Override
	public Account save (Account account) {

		Map idInfo = null;

		try {
			idInfo = IdentityUtil.getCarInfo(account.getIdentity());
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(idInfo != null) {
			account.setAge(Integer.parseInt(idInfo.get("age").toString()));
			account.setBirthday(idInfo.get("birth").toString());
			account.setGender(Integer.parseInt(idInfo.get("sex").toString()));
		}
		if (account.getPassword() == null) {
			String tempPass = PinYinUtil.getPingYin(account.getName());
			account.setPassword(new BCryptPasswordEncoder().encode(tempPass));
		} else {
			account.setPassword(new BCryptPasswordEncoder().encode(account.getPassword()));
		}

		//执行保存
		Account result = accountRepo.saveAndFlush(account);

		return result;
	}

	/**
	 * 插入，批量保存
	 *
	 * @param list
	 * @return List<Account>
	 */
	@Override
	public List<Account> insertObjInBatch (List<Account> list) {
		return null;
	}

	/**
	 * 更新
	 *
	 * @param account 跟新的实体
	 * @return
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public Account update (Account account) {

		Account dbResult = accountRepo.saveAndFlush(account);

		return dbResult;
	}

	/**
	 * 删除--批量删除
	 *
	 * @param ids 批量删除id
	 * @return
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public int delete (Long[] ids) {

		int flagNum = accountRepo.deleteByIdIn(ids);
		if (flagNum > 0) {
			//删除关系表的数据
			accountRepo.deleteRelationWhileDeleteUser(ids);
		}
		return flagNum;
	}

	/**
	 * 获取列表数据
	 *
	 * @param pageable
	 * @return Page<Account>
	 */
	@Override
	public Page<Account> list (Pageable pageable, Map params) {

        if (StringUtils.isNotBlank(params.get("queryStr").toString())) {
            params.put("name_username_mobile_email_identity_birthday_address_plike", params.get("queryStr"));
            params.remove("queryStr");
        }

		Specification specification = DynamicSpecifications.bySearchFilter(SearchFilter.parse(params).values(), Account.class);

		Page<Account> result = accountRepo.findAll(specification, pageable);

		return result;
	}

	/**
	 * 获取单体 数据
	 *
	 * @param id 获取详情的id
	 * @return
	 */
	@Override
	public Account info (Long id) {
		Account dbResult = accountRepo.getOne(id);
		return dbResult;
	}

	/**
	 * 上传文件
	 *
	 * @param inputStream
	 */
	@Override
	public Integer uploadXlsFile (InputStream inputStream) {

		List<Account> extactResult = null;

		//导入设置

		try {

			extactResult = ExcelImportUtil.importExcel(inputStream, Account.class, new ImportParams());

			if (extactResult.size() > 0) {

				for (int i = 0; i < extactResult.size(); i++) {

					Account account = extactResult.get(i);
					Map idsInfo = IdentityUtil.getCarInfo(account.getIdentity());
					account.setAge((Integer) idsInfo.get("age"));
					account.setBirthday(idsInfo.get("birth").toString());
					account.setGender(Integer.parseInt(idsInfo.get("sex").toString()));

					if (account.getUsername() == null) {
						account.setUsername(PinYinUtil.getPingYin(account.getName()));
					}

					account.setPassword(new BCryptPasswordEncoder().encode(account.getUsername()));

				}

				accountRepo.saveAll(extactResult);

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return extactResult.size();
	}

	/**
	 * 修改密码
	 *
	 * @param id          用户id
	 * @param newPassword 新密码
	 * @return 数据库影响数
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public Integer changePassword (Long id, String newPassword) {

		return accountRepo.changePassword(id, new BCryptPasswordEncoder().encode(newPassword));
	}

	@Override
	public boolean comparePassword (Long id, String inputPassword) {

		boolean result = false;
		String password = accountRepo.getPassword(id);

		if (password != null) {
			BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
			return bCryptPasswordEncoder.matches(inputPassword, password);
		}

		return result;
	}

	/**
	 * 移除当前岗位中的 用户关联
	 *
	 * @param ids  用户Id的数组
	 * @param type 清空的类型  0 为部门，1 为 岗位
	 * @return 影响数
	 */
	@Transactional(rollbackOn = Exception.class)
	@Override
	public Integer removeOrgOrPostInfo (Long[] ids, Integer type) {
		Integer flag = type.equals(0) ? accountRepo.setOrgInfoNull(ids) : accountRepo.setPostInfoNull(ids);
		return flag;
	}

	/**
	 * 查找 对应角色id的 对用用户数据
	 *
	 * @param pageable    分页数据
	 * @param searchParam 查询类容
	 * @param roleId      角色Id
	 * @return List<Map>
	 */
	@Override
	public Page<Map> loadUserByRoleIdIn (Pageable pageable, String searchParam, Long roleId) {
		return accountRepo.loadUserByRoleIdIn(roleId, searchParam, pageable);
	}

	/**
	 * 获取角色没有 关联的用户 数据
	 *
	 * @param pageable    分页数据
	 * @param searchParam 查询类容
	 * @param roleId      角色Id
	 * @return Page<Map>
	 */
	@Override
	public Page<Map> loadUserByRoleIdOut (Pageable pageable, String searchParam, Long roleId) {
		return accountRepo.loadUserByRoleIdOut(roleId, searchParam, pageable);
	}

	@Override
	public Page<Map> getAccountByRoleName(Pageable pageable, String roleName) {
		return accountRepo.getAccountByRoleName(roleName, pageable);
	}
}
